﻿using Abp;
using Abp.AutoMapper;
using Abp.Dependency;
using Abp.EntityFrameworkCore;
using Abp.EntityFrameworkCore.Configuration;
using Abp.Modules;
using Abp.Reflection.Extensions;
using Batman.Cms.Core;
using Batman.Cms.Core.Const;
using Batman.Jianbei.Forum.Core.Datas;
using Batman.Jianbei.Forum.Core.Domains;
using Batman.Jianbei.Forum.Jobs;
using Batman.Jianbei.Forum.Repositories.Mongo;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MongoDB.Driver;
using System;
using System.Linq;

namespace Batman.Jianbei.Forum.APP_Start
{
    [DependsOn(
        typeof(AbpEntityFrameworkCoreModule),
        typeof(AbpAutoMapperModule),
        typeof(AbpKernelModule),
        typeof(BatmanCoreModule)
    )]
    public class JianbeiForumModule : AbpModule
    {
        private IConfiguration AspNetConfiguration;

        public JianbeiForumModule(IConfiguration configuration)
        {
            AspNetConfiguration = configuration;
        }

        public override void PreInitialize()
        {
            //ForumInterceptorRegister.Initialize(IocManager.IocContainer.Kernel);

            // ABP的DbContext配置在这边 不要在startup AddDbContext 否则会出现501网关错误
            var connectionString = AspNetConfiguration.GetConnectionString("Default");
            Configuration.Modules.AbpEfCore().AddDbContext<JianbeiForumDbContext2>(options =>
            {
                options.DbContextOptions.UseMySql(connectionString);
            });

            Configuration.Modules.AbpEfCore().AddDbContext<ChatRoomDbContext>(options =>
            {
                options.DbContextOptions.UseMySql(connectionString);
            });

            var mongoConnectionString = AspNetConfiguration.GetConnectionString("Mongo");
            IocManager.Register<MongoClient>(DependencyLifeStyle.Singleton);
            IocManager.Resolve<MongoClient>(new { connectionString = mongoConnectionString });
        }

        public override void Initialize()
        {
            var BatmanCoreModuleAss = typeof(BatmanCoreModule).GetAssembly();
            IocManager.RegisterAssemblyByConvention(BatmanCoreModuleAss);

            var ass = typeof(JianbeiForumModule).GetAssembly();
            IocManager.RegisterAssemblyByConvention(ass);

            var identityAss = typeof(UserManager<>).GetAssembly();
            IocManager.RegisterAssemblyByConvention(identityAss);

            var signarRAss = typeof(IHubContext<>).GetAssembly();
            IocManager.RegisterAssemblyByConvention(signarRAss);

            Configuration.Caching.Configure("forum_home",
                cache => { cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(1); });
            Configuration.Caching.Configure("forum_summary",
                cache => { cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(1); });

            IocManager.Register(typeof(MongoRepositoryBase<>), DependencyLifeStyle.Singleton);

            ChatroomRegister.SchedulerShow(); // 启动轮询调度
        }

        public override void PostInitialize()
        {
            InitUser();
        }

        private async void InitUser()
        {
            var userManager = IocManager.Resolve<UserManager<User>>();

            var context = new JianbeiForumDbContextFactory().CreateDbContext(null);

            if (!context.Roles.Any())
            {
                var supreadmin = new IdentityRole { Name = "超级管理员", NormalizedName = SysRole.SUPER_ADMIN };
                var admin = new IdentityRole { Name = "管理员", NormalizedName = SysRole.ADMIN };
                await context.Roles.AddAsync(supreadmin);
                await context.Roles.AddAsync(admin);
                await context.SaveChangesAsync();
            }

            if (!userManager.Users.Any())
            {
                var user = new User { UserName = "admin" };
                user.SetPassword("admin@123");
                await userManager.CreateAsync(user);

                var role = context.Roles.FirstOrDefault(t => t.NormalizedName == SysRole.SUPER_ADMIN);
                context.UserRoles.Add(new IdentityUserRole<string>
                {
                    UserId = user.Id,
                    RoleId = role.Id
                });
                context.SaveChanges();
            }
        }
    }
}